#include "TraitementRegles.h"


/*************************************************************************
                        TraitementRegles  -  description
                             -------------------

*************************************************************************/

//---------- Réalisation de la tâche <TraitementRegles> (fichier TraitementRegles.c) ---



//------------------------------------------------------ Fonctions privées
void EnvoyerInfosActionneurBal(char * idActionneur, char * val)
{
	MsgInformation msgInfo;
	int ctrl;

	msgInfo.msgType = 3;
	strcpy(msgInfo.info.idCapteur,idActionneur);

	strcpy(msgInfo.info.valeur,val);
	msgInfo.msgType = 3;
	msgInfo.info.date[0] = '\0';
	msgInfo.info.typeCapteur[0] = '\0';
	//recupererDate(msgInfo.info.date);

	ctrl = msgsnd(balEnvoiProxy, &msgInfo, sizeof(Information),0);
	if(ctrl != -1)
	{
		printf("[TraitementRegles/EnvoyerInfosActionneurBal] Message envoyé \n");
	}
	else
	{
		perror("[TraitementRegles/EnvoyerInfosActionneurBal] Erreur d'envoi \n");
	}
}

void TraiterRegle(char *buffer[])
{
	printf("[TraitementRegles/EnvoiActionProxy] Test de la règle: %s\n",buffer[3]);
	if(strcmp(buffer[5],"<") == 0 )
	{
		if(atof(buffer[6]) < atof(buffer[4]))
		{
			printf("[TraitementRegles/EnvoiActionProxy] La règle %s a été déclenchée.\n",buffer[3]);
			EnvoyerInfosActionneurBal(buffer[7],buffer[9]);
			char descrp[100] = "La règle ";
			sprintf(descrp,"%s%s%s",descrp,buffer[3]," est déclenchée");
			logEvent(1 ,descrp);
		}
		else{

		}
	}
	else if(strcmp(buffer[5],">") == 0 )
	{
		if(atof(buffer[6])>atof(buffer[4]))
		{
			printf("[TraitementRegles/EnvoiActionProxy] La règle %s a été déclenchée.\n",buffer[3]);
			EnvoyerInfosActionneurBal(buffer[7],buffer[9]);
			char descrp[100] = "La règle ";
			sprintf(descrp,"%s%s%s",descrp,buffer[3]," est déclenché");
			logEvent(1 ,descrp);
		}
		else{

		}
	}
	else if(strcmp(buffer[5],"=") == 0 )
	{
		if(atof(buffer[4])==atof(buffer[6]))
		{
			printf("[TraitementRegles/EnvoiActionProxy] La règle %s a été déclenchée.\n",buffer[3]);
			EnvoyerInfosActionneurBal(buffer[7],buffer[9]);
			char descrp[100] = "La règle ";
			sprintf(descrp,"%s%s%s",descrp,buffer[3]," est déclenché");
			logEvent(1 ,descrp);
		}
		else{

		}
	}
	else if(strcmp(buffer[5],"!=") == 0 )
	{
		if(atof(buffer[4])!= atof(buffer[6]))
		{
			printf("[TraitementRegles/EnvoiActionProxy] La règle %s a été déclenchée.\n",buffer[3]);
			EnvoyerInfosActionneurBal(buffer[7],buffer[9]);
			char descrp[100] = "La règle ";
			sprintf(descrp,"%s%s%s",descrp,buffer[3]," est déclenché");
			logEvent(1 ,descrp);
		}
		else{

		}
	}
}


void TraitementReglesMoteur()
{
	
	while(1)
	{
		MYSQL mysql;
		MYSQL_RES *result = NULL;
		MYSQL_ROW *row = NULL;

		//Requête qui sélectionne toutes les règles de chaque capteur avec la dernière valeur mesurée
		char requeteBDD[] = "SELECT DISTINCT s.idSource, nomSource, r.idRegle, nomRegle, valeurSeuil, operateurCondition, valeurMesure, ar.identifiantActionneur, nomActionneur, valeur FROM regle r, source s, conditionreglesource c, mesure m, actionregle a, actionneur ar, actionpossible ap WHERE r.idRegle = c.idRegle AND c.idSource = s.idSource AND s.idSource = m.idSource AND c.idRegle = a.idRegle AND a.idActionneur = ar.idActionneur AND a.idActionPossible = ap.idActionPossible AND etat = 1 AND m.valeurMesure = (SELECT valeurMesure FROM mesure, source WHERE source.idSource = s.idSource AND mesure.idSource = source.idSource ORDER BY dateMesure DESC LIMIT 1);";
		mysql_init(&mysql);
		//Connexion à la BDD
		if (mysql_real_connect(&mysql, MYSQL_HOST, MYSQL_LOGIN, MYSQL_PASSWD, MYSQL_DB, 0, NULL, 0) == NULL) {
			printf("[TraitementRegles/TraitementReglesMoteur] Erreur de connexion à la BDD : %s\n", mysql_error(&mysql));
			mysql_close(&mysql);
		}
		else if (mysql_select_db(&mysql,MYSQL_DB) == 0) {
			//printf("[TraitementRegles/TraitementReglesMoteur] Connecté à la BDD!\n");

			if(mysql_query(&mysql, requeteBDD))
			{
				printf("[TraitementRegles/TraitementReglesMoteur] Erreur requête\n");
			}
			else
			{
				//Déclaration des pointeurs de structure
				unsigned int i = 0;
				unsigned int num_champs = 0;

				//On met le jeu de résultat dans le pointeur result
				result = mysql_store_result(&mysql);
				if(result)
				{
					//On récupère le nombre de champs
					num_champs = mysql_num_fields(result);

					//Tant qu'il y a encore un résultat ...
					while ((row = mysql_fetch_row(result)))
					{
						//On déclare un pointeur long non signé pour y stocker la taille des valeurs
						unsigned long *lengths;

						//On stocke cette taille dans le pointeur
						lengths = mysql_fetch_lengths(result);

						//On fait une boucle pour avoir la valeur de chaque champs
						char *buffReq[num_champs];
						for(i = 0; i < num_champs; i++)
						{
							buffReq[i] = malloc((strlen(row[i])+1)*sizeof(char));
							strcpy (buffReq[i],row[i]);
						}
						printf("\nContenu du buffer : ");
						for(i = 0; i < num_champs; i++)
						{
							printf("%s, ",buffReq[i]);
						}
						printf("\n");
						//Exécution des règles
						TraiterRegle(buffReq);

						//Libération du buffer
						for(i = 0; i < num_champs; i++)
						{
							free(buffReq[i]);
						}
					}
					//Libération du jeu de résultat
					mysql_free_result(result);
				}
				else
				{
					if (mysql_errno(&mysql))
					{
						fprintf(stderr, "[TraitementRegles/TraitementReglesMoteur] Erreur: %s\n", mysql_error(&mysql));
					}
					else if (mysql_field_count(&mysql) == 0)
					{
						printf("[TraitementRegles/TraitementReglesMoteur] aucune règle trouvée\n");
					}
				}
			}
		}
		else {
			perror("[TraitementRegles/TraitementReglesMoteur] Erreur de connexion à la BDD!\n");
		}
		printf("[TraitementRegles/TraitementReglesMoteur] Fermeture de la connexion\n");
		mysql_close(&mysql);

		//On endort la tâche pour ne pas vérifier constamment les règles alors qu'il n'y a pas de nouvelles valeurs dans la BDD
		sleep(5);
	}
}


//////////////////////////////////////////////////////////////////  PUBLIC
//---------------------------------------------------- Fonctions publiques
void TraitementRegles(void* balProxy)
{
	balEnvoiProxy = (int)balProxy;
	TraitementReglesMoteur();
}
